package nsqp

import (
	"bgs/conf"
	"bgs/db"
	"bgs/grpc/imp/enums"
	handlers "bgs/nsqp/handlers/trigger"
	"bgs/nsqp/topic"
	"bgs/nsqp/util"
	activityService "bgs/service/activity"
	ledgerService "bgs/service/ledger"
	orderService "bgs/service/order"
	userService "bgs/service/user"
	retryRunner "bgs/nsqp/runners/retry"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
)

// TriggerProxy proxy compensation nsq message
type TriggerProxy struct {
	slog *zap.SugaredLogger
	subs []*nsq.Consumer
}

// NewTriggerProxy initialization
func NewTriggerProxy(
	nsqConf conf.NsqSection,
	pgdao *db.PgDao,
	slog *zap.SugaredLogger,
	failover *util.NsqFailover,
	retryRunner *retryRunner.NsqRetryRunner,
	activityService *activityService.ActivityServiceImp,
	ledgerService *ledgerService.LedgerServiceImp,
	orderService *orderService.OrderServiceImp,
	userService *userService.UserServiceImp,
) (proxy *TriggerProxy, err error) {
	proxy = &TriggerProxy{
		slog: slog,
	}
	config := nsq.NewConfig()

	producer, err := nsq.NewProducer(nsqConf.NsqdAddress, config)
	if err != nil {
		return
	}
	producer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)

	// settleProfitedOrderConsumer.go
	settleProfitedOrderConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.SettleProfitedOrder)
	settleProfitedOrderConsumer, err := nsq.NewConsumer(settleProfitedOrderConsumerTopic, appID, config)
	if err != nil {
		return
	}
	settleProfitedOrderConsumer.SetLogger(nsqLogger, nsq.LogLevelError)
	settleProfitedOrderConsumer.AddHandler(handlers.NewSettleProfitedOrderHandler(pgdao, slog, settleProfitedOrderConsumerTopic, failover,
		orderService, userService))
	err = settleProfitedOrderConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, settleProfitedOrderConsumer)

	// sendActivityRemindNotificationConsumer.go
	sendActivityRemindNotificationConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.SendActivityRemindNotification)
	sendActivityRemindNotificationConsumer, err := nsq.NewConsumer(sendActivityRemindNotificationConsumerTopic, appID, config)
	if err != nil {
		return
	}
	sendActivityRemindNotificationConsumer.SetLogger(nsqLogger, nsq.LogLevelError)
	sendActivityRemindNotificationConsumer.AddHandler(handlers.NewSendCheckIn1RemindNotificationHanlder(pgdao, slog, sendActivityRemindNotificationConsumerTopic,
		failover, activityService))
	err = sendActivityRemindNotificationConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, sendActivityRemindNotificationConsumer)

	// submitOrderProfitShareAtAfterSaleDeadlineConsumer.go
	submitOrderProfitShareAtAfterSaleDeadlineConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.SubmitOrderProfitShareAtAfterSaleDeadline)
	submitOrderProfitShareAtAfterSaleDeadlineConsumer, err := nsq.NewConsumer(submitOrderProfitShareAtAfterSaleDeadlineConsumerTopic, appID, config)
	if err != nil {
		return
	}
	submitOrderProfitShareAtAfterSaleDeadlineConsumer.SetLogger(nsqLogger, nsq.LogLevelError)
	submitOrderProfitShareAtAfterSaleDeadlineConsumer.AddHandler(handlers.NewSubmitOrderProfitShareAtAfterSaleDeadlineHandler(pgdao, slog, submitOrderProfitShareAtAfterSaleDeadlineConsumerTopic, failover,
		ledgerService, orderService))
	err = submitOrderProfitShareAtAfterSaleDeadlineConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, submitOrderProfitShareAtAfterSaleDeadlineConsumer)

	// retryNsqFailConsumer
	retryNsqFailConsumerTopic := topic.Make(enums.AppIDBGAPI)(topic.RetryNsqFail)
	retryNsqFailConsumer, err := nsq.NewConsumer(retryNsqFailConsumerTopic, appID, config)
	if err != nil {
		return
	}
	retryNsqFailConsumer.SetLogger(nsqLogger, nsq.LogLevelError)
	retryNsqFailConsumer.AddHandler(handlers.NewRetryNsqFailHandler(pgdao, slog, retryRunner))
	err = retryNsqFailConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, retryNsqFailConsumer)

	// Gracefully stop the consumer.
	// consumer.Stop()

	return
}
